#include "rfid_device.hpp"
#include "detail/taihesen_rfid.hpp"

#include <log/log.hpp>

namespace sros::device
{
    RfidDevice::RfidDevice(std::shared_ptr<McuDevice> mcu_device)
        : device_impl<cfg::RfidCfg>(), mcu_(mcu_device), rfid_(nullptr)
    {
    }

    RfidDevice::~RfidDevice()
    {
    }

    void RfidDevice::install_event(EventCb cb)
    {
        if (rfid_)
        {
            rfid_->install_event(cb);
        }
    }

    RetBool RfidDevice::init()
    {
        // 加载配置
        auto ret = load_config();
        if (!ret.v)
        {
            return ret;
        }

        ret = init_device_();
        if (!ret.v)
        {
            return ret;
        }

        if (rfid_)
        {
            rfid_->init();
        }

        return {true};
    }

    void RfidDevice::run()
    {
        if (rfid_)
        {
            rfid_->run();
        }
    }

    void RfidDevice::close()
    {
        {
            std::lock_guard<std::mutex> lck(mtx_);
            if (rfid_)
            {
                rfid_->close();
            }
        }

        if (config_)
        {
            config_->deinit();
            config_ = nullptr;
        }
    }

    void RfidDevice::parse(const device::proto::RspUartMsg &uart_msg)
    {
        std::lock_guard<std::mutex> lck(mtx_);

        if (rfid_)
        {
            rfid_->parse(uart_msg);
        }
    }

    RetBool RfidDevice::load_config()
    {
        if (config_)
        {
            return {true};
        }

        std::string root = util::env_var("HOME");
        if (root.empty())
        {
            root = ".";
        }
        std::string config_path = util::format("{}/.sros/{}/{}/config/rfid_config.json", root, MODULE, NODE);

        config_ = std::make_shared<commons::Config<cfg::RfidCfg>>();
        auto ret = config_->init(config_path);
        if (!ret.v)
        {
            return ret;
        }

        return config_->load();
    }

    RetBool RfidDevice::init_device_()
    {
        cfg::RfidCfg l_cfg;
        auto ret = config_->get(l_cfg);
        if (!ret.v)
        {
            return ret;
        }

        if (!l_cfg.enable)
        {
            return {true};
        }
        
        if (l_cfg.type == cfg::RfidType::TAIHESEN)
        {
            rfid_ = std::make_shared<detail::TaiHeSenRfid>(l_cfg.uart_index, mcu_);
        }
        else 
        {
            return {false, "not support rfid type"};
        }
        
        return {true};
    }
}